package com.group.project.hrms.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.group.project.hrms.entity.*;
import com.group.project.hrms.entity.DingResultEntity.DingProcessTemplateEntity;
import com.group.project.hrms.entity.ResultEntity.ResultEntity;
import com.group.project.hrms.service.*;
import com.group.project.hrms.utils.DateUtil;
import com.group.project.hrms.utils.DingAccessUtils;
import com.group.project.hrms.utils.LogUtil;
import com.group.project.hrms.utils.UUIDUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.util.*;

@Controller
public class AttendanceGroupInfoController {

    @Autowired
    private IAttendanceGroupInfoService iAttendanceGroupInfoService;

    @Autowired
    private IAttendanceGroupStaffsService iAttendanceGroupStaffsService;

    @Autowired
    private IAttendanceGroupDeptsService iAttendanceGroupDeptsService;

    @Autowired
    private ICheckPointInfoService iCheckPointInfoService;

    @Autowired
    private IAttendanceShiftInfoService iAttendanceShiftInfoService;

    @Autowired
    private IRestTimeSettingsService iRestTimeSettingsService;

    @Autowired
    private ISpecialCheckDateService iSpecialCheckDateService;

    @Autowired
    private IOvertimeRulesService iOvertimeRulesService;

    @Autowired
    private DingAccessUtils dingAccessUtils;

    @Autowired
    private IHolidayRecordService iHolidayRecordService;

    @Autowired
    private IHolidayListService iHolidayListService;

    @Autowired
    private DateUtil dateUtil;

    @Autowired
    private IContactBasicService iContactBasicService;

    @Autowired
    private IContactBasicDeptInfoService iContactBasicDeptInfoService;

    @Autowired
    private IAttendanceGroupDeptAdjustRecordService iAttendanceGroupDeptAdjustRecordService;

    @Autowired
    private IAttendanceGroupStaffAdjustRecordService iAttendanceGroupStaffAdjustRecordService;

    @Autowired
    private LogUtil logUtil;


    /**
     * 该方法是前端考勤基础设置初始化信息页面，即一次性获取页面所需的数据
     * @param request http请求
     * @return 标准返回值对象
     */
    @RequestMapping("/basic/getAllAttendanceBasicInfos")
    @ResponseBody
    public ResultEntity getAllAttendanceBasicInfos(HttpServletRequest request){
        ResultEntity resultEntity = new ResultEntity();
        try{
            //获取所有考勤基础设置表信息(考勤组信息表，考勤组关联的人员表，考勤组关联的部门表，考勤和行政打卡时间和范围表，考勤时间设定表，考勤班次表，休息时段表，工作日设置表，特殊打卡日期表，加班规则设定表)
            List<AttendanceGroupInfo> attendanceGroupInfos = iAttendanceGroupInfoService.selectAllAttendanceGroupInfo();
            List<AttendanceGroupStaffs> attendanceGroupStaffs = iAttendanceGroupStaffsService.selectAllAttendanceGroupStaffs();
            List<AttendanceGroupDepts> attendanceGroupDepts = iAttendanceGroupDeptsService.selectAllAttendanceGroupDepts();
            List<CheckPointInfo> checkPointInfos = iCheckPointInfoService.selectAllCheckPointInfo();
            //List<AttendanceDateSettings> attendanceDateSettings = iAttendanceDateSettingsService.selectAllAttendanceDateSettings();
            List<AttendanceShiftInfo> attendanceShiftInfos = iAttendanceShiftInfoService.selectAllAttendanceShiftInfo();
            List<RestTimeSettings> restTimeSettings = iRestTimeSettingsService.selectAllRestTimeSettings();
            List<SpecialCheckDate> specialCheckDates = iSpecialCheckDateService.selectAllSpecialCheckDate();
            List<OvertimeRules> overtimeRules = iOvertimeRulesService.selectAllOvertimeRules();

            //获取假日信息
            List<HolidayRecord> holidayRecords = iHolidayRecordService.selectAllHolidayRecord();
            List<HolidayList> holidayLists = iHolidayListService.selectAllHolidayList();

            //获取钉钉中所有可管理的流程模板信息
            List<DingProcessTemplateEntity> processTemplateEntities = dingAccessUtils.getAllManagedProcessTemplate();

            //获取人员和部门信息
            List<ContactBasic> contactBasicList = iContactBasicService.selectAllContactBasic();
            List<ContactBasicDeptInfo> deptInfoList = iContactBasicDeptInfoService.selectAllContactBasicDeptInfo();

            //创建Map对象，用于返回给前端
            Map<String, List> resultMap = new HashMap<>();
            resultMap.put("attendanceGroupInfos", attendanceGroupInfos);
            resultMap.put("attendanceGroupStaffs", attendanceGroupStaffs);
            resultMap.put("attendanceGroupDepts", attendanceGroupDepts);
            resultMap.put("checkPointInfos", checkPointInfos);
            //resultMap.put("attendanceDateSettings", attendanceDateSettings); //计划取消
            resultMap.put("attendanceShiftInfos", attendanceShiftInfos);
            resultMap.put("restTimeSettings", restTimeSettings);
            resultMap.put("specialCheckDates", specialCheckDates);
            resultMap.put("overtimeRules", overtimeRules);
            resultMap.put("processTemplateEntities", processTemplateEntities);
            resultMap.put("holidayRecords", holidayRecords);
            resultMap.put("holidayLists", holidayLists);
            resultMap.put("contactBasicList", contactBasicList);
            resultMap.put("deptInfoList", deptInfoList);

            //创建List对象，用于存放Map结果集
            List<Map> mapList = new ArrayList<>();
            mapList.add(resultMap);
            resultEntity.setCode("S");
            resultEntity.setMsg("Success");
            resultEntity.setDataList(mapList);
            return resultEntity;
        }catch (Exception e){
            resultEntity.setCode("F");
            resultEntity.setMsg("加载考勤基础数据失败");
        }
        return resultEntity;
    }

    /**
     * 该方法将接收前端传来的创建考勤组的参数，并向数据库创建新考勤组
     * @param map 考勤组数据
     * @param request http请求
     * @return 标准返回值对象
     */
    @RequestMapping("/basic/insertAttendanceGroupInfo")
    @ResponseBody
    public ResultEntity insertAttendanceGroupInfo(@RequestBody Map map, HttpServletRequest request){
        return this.doInsertOrUpdateAttendanceGroupInfo(map, "insert");
    }

    /**
     * 该方法将接收前端传来的更新考勤组的参数，并向数据库更新已经存在的考勤组
     * @param map 考勤组数据
     * @param request http请求
     * @return 标准返回值对象
     */
    @RequestMapping("/basic/updateAttendanceGroupInfo")
    @ResponseBody
    public ResultEntity updateAttendanceGroupInfo(@RequestBody Map map, HttpServletRequest request){
        return this.doInsertOrUpdateAttendanceGroupInfo(map, "update");
    }

    /**
     * 该方法接收前端传来的修改关联部门、特殊打卡或者不打卡日期，删除关联部门或者打卡与不打卡日期的操作
     * @param map 前端传入的数据集合
     * @param request http请求
     * @return 标准返回值对象
     */
    @RequestMapping("/basic/editAttendanceGroupInfo")
    @ResponseBody
    public ResultEntity editAttendanceGroupInfo(@RequestBody Map map, HttpServletRequest request){
        ResultEntity resultEntity = new ResultEntity();
        Date date = new Date();
        Object staffName = request.getAttribute("staffName");
        Object groupID = map.get("groupID");
        Object flag = map.get("flag");
        if(null != groupID && null != flag){
            AttendanceGroupInfo info = iAttendanceGroupInfoService.selectOneAttendanceGroupInfoByAgId(groupID.toString());
            //AttendanceDateSettings settings = iAttendanceDateSettingsService.selectAttendanceDateSettingsBySettingsID(info.getAttendanceDateId());
            if("adddept".equals(flag)){ //增加一个部门
                //System.out.println(map);
                JSONObject orgObject = JSON.parseObject(JSON.toJSONString(map.get("data")));
                JSONArray orgArray = orgObject.getJSONArray("AddDept");
                try{
                    for (Object deptID : orgArray
                         ) { //校验部门是否已经存在
                        AttendanceGroupDepts dept = iAttendanceGroupDeptsService.selectAttendanceGroupDeptsByDeptID(deptID.toString());
                        if(null != dept){
                            AttendanceGroupInfo groupInfo = iAttendanceGroupInfoService.selectOneAttendanceGroupInfoByAgId(dept.getAttendanceGroupId());
                            ContactBasicDeptInfo deptInfo = iContactBasicDeptInfoService.selectOneContactBasicDeptInfoByDeptID(dept.getDeptId());
                            resultEntity.setCode("F");
                            resultEntity.setMsg("部门：" + deptInfo.getDeptName() + " 已经存在于考勤组：" + groupInfo.getAttendanceGroupName() + " 中，请先删除再添加!");
                            return resultEntity;
                        }
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
                int count = 0;
                for (Object did : orgArray
                     ) {
                    AttendanceGroupDepts targetGroupDept = new AttendanceGroupDepts();
                    targetGroupDept.setcTime(date);
                    targetGroupDept.setAttendanceGroupId(groupID.toString());
                    targetGroupDept.setDeptId(Long.valueOf(did.toString()));
                    count = count + iAttendanceGroupDeptsService.insertAttendanceGroupDepts(targetGroupDept);

                    //增加异动记录
                    AttendanceGroupDeptAdjustRecord adjustRecord = new AttendanceGroupDeptAdjustRecord();
                    adjustRecord.setcTime(date);
                    adjustRecord.setAction(2); //2表示新增，1表示删除
                    adjustRecord.setDeptId(Long.valueOf(did.toString()));
                    adjustRecord.setAttendanceGroupId(groupID.toString());
                    iAttendanceGroupDeptAdjustRecordService.insertAttendanceGroupDeptAdjustRecord(adjustRecord);
                }
                resultEntity.setCode("S");
                resultEntity.setMsg("添加成功，共计添加：" + count + " 个部门!");
                logUtil.insertSystemEventLog(staffName.toString(), date, "向考勤组: " + info.getAttendanceGroupName() + " 中新增了" + count + "个部门", "考勤");
            }
            if("deldept".equals(flag)){ //删除一个部门
                //System.out.println(map);
                JSONObject orgObject = JSON.parseObject(JSON.toJSONString(map.get("data")));
                Long targetDeptID = orgObject.getLong("deleteDeptID");
                AttendanceGroupDepts groupDepts = iAttendanceGroupDeptsService.selectAttendanceGroupDeptsByDeptID(targetDeptID.toString());
                int count = iAttendanceGroupDeptsService.deleteAttendanceGroupDepts(groupDepts);

                //增加异动记录
                AttendanceGroupDeptAdjustRecord adjustRecord = new AttendanceGroupDeptAdjustRecord();
                adjustRecord.setcTime(date);
                adjustRecord.setAction(1); //2表示新增，1表示删除
                adjustRecord.setDeptId(Long.valueOf(targetDeptID.toString()));
                adjustRecord.setAttendanceGroupId(groupID.toString());
                iAttendanceGroupDeptAdjustRecordService.insertAttendanceGroupDeptAdjustRecord(adjustRecord);

                if(count != 0){
                    resultEntity.setCode("S");
                    resultEntity.setMsg("删除成功!");
                    logUtil.insertSystemEventLog(staffName.toString(), date, "从考勤组: " + info.getAttendanceGroupName() + " 删除了一个部门", "考勤");
                }
            }
            if("addspb".equals(flag)){ //添加一个特殊打卡日期
                //System.out.println(map);
                JSONObject orgObject = JSON.parseObject(JSON.toJSONString(map.get("data")));
                JSONArray orgArray = orgObject.getJSONArray("AddSpecialDate");
                String spCheckIDs = info.getSpecialCheckIds();
                JSONArray checkIDs = null == spCheckIDs ? null : JSON.parseArray(spCheckIDs);
                try{
                    if(null != checkIDs){
                        for (Object checkID : checkIDs
                        ) { //校验要添加的日期是否已经存在
                            SpecialCheckDate sp = iSpecialCheckDateService.selectOneSpecialCheckDateBySpID(checkID.toString());
                            Date spDate = sp.getSpecialDate();
                            for (Object orgDateObject : orgArray
                            ) {
                                String orgDate = JSON.parseObject(JSON.toJSONString(orgDateObject)).getString("checkDate");
                                Date org = dateUtil.formatDateByString(orgDate);
                                if(dateUtil.getYearByDate(spDate) == dateUtil.getYearByDate(org) && dateUtil.getMonthByDate(spDate) == dateUtil.getMonthByDate(org) && dateUtil.getDayByDate(spDate) == dateUtil.getDayByDate(org)){
                                    resultEntity.setCode("F");
                                    resultEntity.setMsg("您要添加的日期：" + orgDate.substring(0, 10) + " 已经存在");
                                    return resultEntity;
                                }
                            }
                        }
                    }
                    //开始插入数据
                    List<String> newSpIDs = new ArrayList<>();
                    int count = 0;
                    for (Object orgDateObject : orgArray
                    ) {
                        String orgDate = JSON.parseObject(JSON.toJSONString(orgDateObject)).getString("checkDate");
                        Date org = dateUtil.formatDateByString(orgDate);
                        String id = UUIDUtil.createUUID();
                        newSpIDs.add(id);
                        SpecialCheckDate specialCheckDate = new SpecialCheckDate();
                        specialCheckDate.setcTime(date);
                        specialCheckDate.setCheckFlag("B");
                        specialCheckDate.setSpecialCheckId(id);
                        specialCheckDate.setSpecialDate(org);
                        count = count + iSpecialCheckDateService.insertSpecialCheckDate(specialCheckDate);
                    }
                    List<String> orgList = (null == checkIDs) ? null : checkIDs.toJavaList(String.class);
                    if(null != orgList){
                        newSpIDs.addAll(orgList);
                    }

                    //settings.setSpecialCheckIds(JSON.toJSONString(orgList));
                    //iAttendanceDateSettingsService.updateAttendanceDateSettings(settings);
                    info.setSpecialCheckIds(JSON.toJSONString(newSpIDs));
                    iAttendanceGroupInfoService.updateAttendanceGroupInfo(info);
                    resultEntity.setCode("S");
                    resultEntity.setMsg("添加成功");
                    logUtil.insertSystemEventLog(staffName.toString(), date, "向考勤组: " + info.getAttendanceGroupName() + " 添加了特殊打卡日期", "考勤");
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
            if("addspa".equals(flag)){ //添加一个特殊不打卡日期
                //System.out.println(map);
                JSONObject orgObject = JSON.parseObject(JSON.toJSONString(map.get("data")));
                JSONArray orgArray = orgObject.getJSONArray("AddSpecialDate");
                try{
                    List<String> spIDList = JSON.parseArray(info.getSpecialCheckIds(), String.class);
                    if(null != spIDList && spIDList.size() != 0){
                        for (String spid : spIDList
                        ) {
                            Date spDate = iSpecialCheckDateService.selectOneSpecialCheckDateBySpID(spid).getSpecialDate();
                            for (Object org : orgArray
                            ) {
                                Date orgDate = dateUtil.formatDateByString(JSONObject.parseObject(JSON.toJSONString(org)).getString("checkDate"));
                                if(spDate.getYear() == orgDate.getYear() && spDate.getMonth() == orgDate.getMonth() && spDate.getDay() == orgDate.getDay()){
                                    resultEntity.setCode("F");
                                    resultEntity.setMsg("您要添加的日期：" + JSONObject.parseObject(JSON.toJSONString(org)).getString("checkDate").substring(0, 10) + " 已经存在");
                                    return resultEntity;
                                }
                            }
                        }
                    }
                    //开始插入数据
                    List<String> newSpIDS = new ArrayList<>();
                    int count = 0;
                    for (Object org : orgArray
                    ) {
                        Date orgDate = dateUtil.formatDateByString(JSONObject.parseObject(JSON.toJSONString(org)).getString("checkDate"));
                        SpecialCheckDate specialCheckDate = new SpecialCheckDate();
                        String id = UUIDUtil.createUUID();
                        newSpIDS.add(id);
                        specialCheckDate.setcTime(date);
                        specialCheckDate.setSpecialCheckId(id);
                        specialCheckDate.setSpecialDate(orgDate);
                        specialCheckDate.setCheckFlag("A");
                        count = count + iSpecialCheckDateService.insertSpecialCheckDate(specialCheckDate);
                    }
                    List<String> orgList = (null == spIDList) ? null : JSON.parseArray(info.getSpecialCheckIds()).toJavaList(String.class);
                    if(null != orgList){
                        newSpIDS.addAll(orgList);
                    }
                    //settings.setSpecialCheckIds(JSON.toJSONString(orgList));
                    //iAttendanceDateSettingsService.updateAttendanceDateSettings(settings);
                    info.setSpecialCheckIds(JSON.toJSONString(newSpIDS));
                    iAttendanceGroupInfoService.updateAttendanceGroupInfo(info);
                    resultEntity.setCode("S");
                    resultEntity.setMsg("添加成功");
                    logUtil.insertSystemEventLog(staffName.toString(), date, "向考勤组: " + info.getAttendanceGroupName() + " 添加了特殊不打卡日期", "考勤");
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
            if("delspa".equals(flag) || "delspb".equals(flag)){ //删除一个特殊打卡或者不不打卡日期
                System.out.println(map);
                JSONObject orgObject = JSON.parseObject(JSON.toJSONString(map.get("data")));
                String spDateID = orgObject.getString("deleteSpDateID");
                iSpecialCheckDateService.deleteSpecialCheckDate(iSpecialCheckDateService.selectOneSpecialCheckDateBySpID(spDateID));
                List<String> spDateList = JSON.parseArray(info.getSpecialCheckIds()).toJavaList(String.class);
                Iterator<String> iterator = spDateList.iterator();
                while (iterator.hasNext()){
                    if(iterator.next().equals(spDateID)){
                        iterator.remove();
                    }
                }
                //settings.setSpecialCheckIds(JSON.toJSONString(spDateList));
                //iAttendanceDateSettingsService.updateAttendanceDateSettings(settings);
                info.setSpecialCheckIds(JSON.toJSONString(spDateList));
                iAttendanceGroupInfoService.updateAttendanceGroupInfo(info);
                resultEntity.setCode("S");
                resultEntity.setMsg("删除成功");
                logUtil.insertSystemEventLog(staffName.toString(), date, "从考勤组: " + info.getAttendanceGroupName() + " 删除了一个特殊打卡或特殊不打卡日期", "考勤");
            }
        }
        return resultEntity;
    }

    /**
     * 该方法接收前端传来的删除考勤组数据，向后台删除一个考勤组
     * @param map 删除考勤组数据
     * @param request http请求
     * @return 标准返回值对象
     */
    @RequestMapping("/basic/deleteAttendanceGroupInfo")
    @ResponseBody
    public ResultEntity deleteAttendanceGroupInfo(@RequestBody Map map, HttpServletRequest request){
        ResultEntity resultEntity = new ResultEntity();
        Object staffName = request.getAttribute("staffName");
        if(null != map){
            Object gid = map.get("groupID");
            if(null != gid){
                AttendanceGroupInfo groupInfo = iAttendanceGroupInfoService.selectOneAttendanceGroupInfoByAgId(gid.toString());
                String spIDs = groupInfo.getSpecialCheckIds();
                try{
                    if(null != spIDs){
                        JSONArray ids = JSONArray.parseArray(spIDs);
                        for (Object id : ids
                        ) {
                            SpecialCheckDate specialCheckDate = iSpecialCheckDateService.selectOneSpecialCheckDateBySpID(id.toString());
                            if(null != specialCheckDate){
                                iSpecialCheckDateService.deleteSpecialCheckDate(specialCheckDate);
                            }
                        }
                    }
                }catch (Exception e){
                    e.printStackTrace();
                    resultEntity.setCode("F");
                    resultEntity.setMsg("删除特殊日期时异常");
                    return resultEntity;
                }

                List<AttendanceGroupStaffs> groupStaffs = iAttendanceGroupStaffsService.selectAttendanceGroupStaffsByGroupID(gid.toString());
                try{
                    if(null != groupStaffs && groupStaffs.size() != 0){
                        for (AttendanceGroupStaffs ags : groupStaffs
                             ) {
                            iAttendanceGroupStaffsService.deleteAttendanceGroupStaffs(ags);
                        }
                    }
                }catch (Exception e){
                    e.printStackTrace();
                    resultEntity.setCode("F");
                    resultEntity.setMsg("删除考勤组所关联的人员列表时异常");
                    return resultEntity;
                }


                List<AttendanceGroupDepts> groupDepts = iAttendanceGroupDeptsService.selectAttendanceGroupDeptsByGroupID(gid.toString());
                try{
                    if(null != groupDepts && groupDepts.size() != 0){
                        for (AttendanceGroupDepts agd : groupDepts
                             ) {
                            iAttendanceGroupDeptsService.deleteAttendanceGroupDepts(agd);
                        }
                    }
                }catch (Exception e){
                    e.printStackTrace();
                    resultEntity.setCode("F");
                    resultEntity.setMsg("删除考勤组所关联的部门列表时异常");
                    return resultEntity;
                }

                //删除人员异动记录和部门异动记录
                try{
                    List<AttendanceGroupStaffAdjustRecord> staffAdjustRecords = iAttendanceGroupStaffAdjustRecordService.selectAttendanceGroupStaffAdjustRecordByGroupID(gid.toString());
                    if(null != staffAdjustRecords && staffAdjustRecords.size() != 0){
                        for (AttendanceGroupStaffAdjustRecord agsr : staffAdjustRecords
                        ) {
                            iAttendanceGroupStaffAdjustRecordService.deleteAttendanceGroupStaffAdjustRecord(agsr);
                        }
                    }
                    List<AttendanceGroupStaffAdjustRecord> staffAdjustRecordsPre = iAttendanceGroupStaffAdjustRecordService.selectAttendanceGroupStaffAdjustRecordByPreGroupID(gid.toString());
                    if(null != staffAdjustRecordsPre && staffAdjustRecordsPre.size() != 0){
                        for (AttendanceGroupStaffAdjustRecord agsr : staffAdjustRecordsPre
                        ) {
                            iAttendanceGroupStaffAdjustRecordService.deleteAttendanceGroupStaffAdjustRecord(agsr);
                        }
                    }
                    List<AttendanceGroupDeptAdjustRecord> deptAdjustRecords = iAttendanceGroupDeptAdjustRecordService.selectAttendanceGroupDeptAdjustRecordByGroupID(gid.toString());
                    if(null != deptAdjustRecords && deptAdjustRecords.size() != 0){
                        for (AttendanceGroupDeptAdjustRecord agdr : deptAdjustRecords
                        ) {
                            iAttendanceGroupDeptAdjustRecordService.deleteAttendanceGroupDeptAdjustRecord(agdr);
                        }
                    }
                }catch (Exception e){
                    e.printStackTrace();
                    resultEntity.setCode("F");
                    resultEntity.setMsg("删除考勤组所关联的异动表时异常");
                    return resultEntity;
                }

                int i = iAttendanceGroupInfoService.deleteAttendanceGroupInfo(groupInfo);
                logUtil.insertSystemEventLog(staffName.toString(), new Date(), "删除了考勤组: " + groupInfo.getAttendanceGroupName(), "考勤");
                if(i != 0){
                    resultEntity.setCode("S");
                    resultEntity.setMsg("Success");
                    return resultEntity;
                }else {
                    resultEntity.setCode("F");
                    resultEntity.setMsg("删除考勤组时异常");
                    return resultEntity;
                }
            }
        }

        resultEntity.setCode("F");
        resultEntity.setMsg("删除失败");
        return resultEntity;
    }

    /**
     * 该方法将接收前端从通讯录列表中变更考勤组操作
     * @param map 要变更的考勤组信息，包含人员ID和考勤组ID
     * @param request http请求
     * @return 标准返回值对象
     */
    @RequestMapping("/basic/changeAttendanceGroupForContact")
    @ResponseBody
    public ResultEntity changeAttendanceGroupForContact(@RequestBody Map map, HttpServletRequest request){
        ResultEntity resultEntity = new ResultEntity();
        Object staffName = request.getAttribute("staffName");
        //System.out.println(map); {groupID=feee9ca5ee, contactID=d409897c2f}
        if(null != map){
            Object groupID = map.get("groupID");
            Object contactID = map.get("contactID");
            Object dateInForce = map.get("dateInForce");
            if(null == dateInForce){
                resultEntity.setCode("F");
                resultEntity.setMsg("生效日期为空");
                return resultEntity;
            }
            Date date = new Date();
            AttendanceGroupStaffs staffs = iAttendanceGroupStaffsService.selectOneAttendanceGroupStaffsByContactID(contactID.toString());
            ContactBasic basic = iContactBasicService.selectContactBasicByContactID(contactID.toString());
            AttendanceGroupDepts depts = iAttendanceGroupDeptsService.selectAttendanceGroupDeptsByDeptID(JSONArray.parseArray(basic.getDept()).getString(0));
            AttendanceGroupStaffAdjustRecord staffAdjustRecord = new AttendanceGroupStaffAdjustRecord(); //创建异动记录对象
            staffAdjustRecord.setcTime(date);
            staffAdjustRecord.setContactId(contactID.toString());
            try{
                staffAdjustRecord.setDateInForce(dateUtil.formatDateByString(dateInForce.toString())); //设置生效日期，从用户处传入
            }catch (Exception e){
                e.printStackTrace();
                resultEntity.setCode("F");
                resultEntity.setMsg("生效日期转换异常");
                return resultEntity;
            }
            if(null == groupID){
                //如果groupID为空，说明用户需要删除操作
                if(null == depts){
                    if(null == staffs){
                        resultEntity.setCode("F");
                        resultEntity.setMsg("该人员尚未加入任何考勤组");
                        return resultEntity;
                    }else {
                        iAttendanceGroupStaffsService.deleteAttendanceGroupStaffs(staffs);

                        //增加异动记录
                        staffAdjustRecord.setAttendanceGroupId(staffs.getAttendanceGroupId());
                        staffAdjustRecord.setAction(1); //1表示删除
                        staffAdjustRecord.setPreviousGroupId(staffs.getAttendanceGroupId());
                        iAttendanceGroupStaffAdjustRecordService.insertAttendanceGroupStaffAdjustRecord(staffAdjustRecord);
                    }
                }else {
                    resultEntity.setCode("F");
                    resultEntity.setMsg("该人员所在的部门绑定了考勤组，修改不成功");
                    return resultEntity;
                }
            }else {
                //说明用户需要更新考勤组
                if(null != staffs){
                    String preID = staffs.getAttendanceGroupId(); //获取变更前的考勤组ID
                    staffs.setAttendanceGroupId(groupID.toString());
                    iAttendanceGroupStaffsService.updateAttendanceGroupStaffs(staffs);

                    //增加异动记录
                    staffAdjustRecord.setAttendanceGroupId(groupID.toString());
                    staffAdjustRecord.setAction(2);//2表示新增
                    staffAdjustRecord.setPreviousGroupId(preID);
                    iAttendanceGroupStaffAdjustRecordService.insertAttendanceGroupStaffAdjustRecord(staffAdjustRecord);
                }else{
                    if(null == depts){
                        AttendanceGroupStaffs groupStaffs = new AttendanceGroupStaffs();
                        groupStaffs.setContactId(contactID.toString());
                        groupStaffs.setAttendanceGroupId(groupID.toString());
                        groupStaffs.setcTime(date);
                        iAttendanceGroupStaffsService.insertAttendanceGroupStaffs(groupStaffs);

                        //增加异动记录
                        staffAdjustRecord.setAttendanceGroupId(groupID.toString());
                        staffAdjustRecord.setAction(2);//2表示新增
                        iAttendanceGroupStaffAdjustRecordService.insertAttendanceGroupStaffAdjustRecord(staffAdjustRecord);
                    }else{
                        resultEntity.setCode("F");
                        resultEntity.setMsg("该人员所在的部门绑定了考勤组，修改不成功");
                        return resultEntity;
                    }
                }
            }
            logUtil.insertSystemEventLog(staffName.toString(), new Date(), " 从通讯录中更新了 " + basic.getStaffName() + " 的考勤组", "考勤");
        }
        resultEntity.setCode("S");
        resultEntity.setMsg("Success");
        return resultEntity;
    }


    /**
     * 传入考勤组数据集合和处理标志，根据插入或者更新标志来向数据库做持久化操作
     * @param map
     * @param flag
     * @return
     */
    private ResultEntity doInsertOrUpdateAttendanceGroupInfo(Map map, String flag){
        ResultEntity resultEntity = new ResultEntity();
        Date date = new Date();
        Object groupName = map.get("groupName"); //考勤组名称String : AGroup01
        Object attendanceType = map.get("attendanceType"); //是否为计件考勤, int : 1表示不是、0表示是
        Object shiftInfo = map.get("shiftInfo"); //ShiftId, String : c6fcc32c9d
        Object ruleInfo = map.get("ruleInfo"); //RuleId, String : 98d9d13d17
        Object workingDays = map.get("workingDays"); //String[] : [A,B,C,D,E,F,G]代表周一到周日
        Object isContainHoliday = map.get("isContainHoliday"); //是否包含节假日 int : 1表示不包含、0表示包含
        Object adminAttendanceDate = map.get("adminAttendanceDate"); //行政考勤打卡时段ID数组 : [d97881bbdb, d3580dd6c4]
        Object depts = map.get("depts"); //部门ID数组 : [371942968, 372074265]
        Object staffs = map.get("staffs"); //员工部门与ContactID对象的数组 : [[371942968, c842d6b643], [371942968, 1dcc51995d], [371942968, 4df4d53dff], [372074265, a3b813d08f], [372074265, 053f2c6a71], [372074266]],
        Object specialCheckDate = map.get("specialCheckDate"); //特殊打卡日期对象数组 : [{ checkDate=2022-04-14T00: 40: 53.337Z }, { checkDate=2022-04-15T00: 40: 58.585Z }]
        Object specialNoCheckDate = map.get("specialNoCheckDate"); //特殊打卡日期对象数组 : [{ noCheckDate=2022-04-18T02: 51: 54.679Z }, { noCheckDate=2022-04-20T02: 51: 57.453Z }]
        //判断创建考勤组必须输入的数据
        if(null != groupName && null != attendanceType && null != shiftInfo &&  null != workingDays && null != isContainHoliday){
            if(flag.equals("insert")){
                //创建考勤组ID
                String groupID = UUIDUtil.createUUID();
                //判断是否存在部门列表，如果存在，就创建AttendanceGroupDepts对象
                List<Long> deptList = null;
                if(null != depts){
                    deptList = JSONArray.parseArray(JSON.toJSONString(depts), Long.class);
                }
                //判断是否存在人员列表，如果存在，就校验并创建AttendanceGroupStaffs对象
                if(null != staffs){
                    JSONArray staffsArray = JSON.parseArray(JSON.toJSONString(staffs));
                    //校验
                    for (Object obj : staffsArray
                    ) {
                        JSONArray staffArray = JSON.parseArray(JSON.toJSONString(obj));
                        //判断这个部门是否已经存在于上述部门列表中
                        if(null != deptList && this.isContainedDept(Long.valueOf(staffArray.getString(0)), deptList)){
                            resultEntity.setCode("F");
                            resultEntity.setMsg("创建失败，原因：选择人员时，其所在的部门已经存在于上一项的部门列表中");
                            return resultEntity;
                        }
                        //部门人员全选的情况下，数组中会只出现一个部门，这种情况需要将部门调整到上一项部门列表中
                        if(staffArray.size() == 1){
                            resultEntity.setCode("F");
                            resultEntity.setMsg("创建失败，原因：不能在单独选择人员时选中整个部门，请将该部门在上一项部门列表中选中即可");
                            return resultEntity;
                        }
                    }
                    //创建AttendanceGroupStaffs对象
                    for (Object staffWithDept : staffsArray
                    ) {
                        JSONArray staffArray = JSON.parseArray(JSON.toJSONString(staffWithDept));
                        String contactID = staffArray.getString(1);
                        AttendanceGroupStaffs groupStaffs = new AttendanceGroupStaffs();
                        groupStaffs.setcTime(date);
                        groupStaffs.setAttendanceGroupId(groupID);
                        groupStaffs.setContactId(contactID);
                        iAttendanceGroupStaffsService.insertAttendanceGroupStaffs(groupStaffs);
                    }
                }
                if(null != deptList){
                    //创建AttendanceGroupDepts对象
                    for (Long deptID : deptList
                    ) {
                        AttendanceGroupDepts groupDepts = new AttendanceGroupDepts();
                        groupDepts.setcTime(date);
                        groupDepts.setDeptId(deptID);
                        groupDepts.setAttendanceGroupId(groupID);
                        iAttendanceGroupDeptsService.insertAttendanceGroupDepts(groupDepts);
                    }
                }
                //判断是否存在特殊打卡日期，如果存在，就创建SpecialCheckDate对象
                List<String> specialCheckIDs = new ArrayList<>();
                if(null != specialCheckDate){
                    List<String> list = this.doInsertSpecialCheckDate(specialCheckDate, date, "B");
                    specialCheckIDs.addAll(list);
                }
                if(null != specialNoCheckDate){
                    List<String> list = this.doInsertSpecialCheckDate(specialNoCheckDate, date, "A");
                    specialCheckIDs.addAll(list);
                }
                //创建记薪考勤打卡时间对象AttendanceDateSettings -- 取消此对象
                //AttendanceDateSettings dateSettings = new AttendanceDateSettings();
                //String dateSettingsID = UUIDUtil.createUUID();
                //dateSettings.setcTime(date);
                //dateSettings.setAttendanceDateId(dateSettingsID);
                //if(specialCheckIDs.size() != 0){
                    //dateSettings.setSpecialCheckIds(JSON.toJSONString(specialCheckIDs));
                //}
                //dateSettings.setAttendanceShiftId(shiftInfo.toString());
                //dateSettings.setIsContainHoliday(Integer.valueOf(isContainHoliday.toString()));
                //dateSettings.setWorkingDay(workingDays.toString());
                //iAttendanceDateSettingsService.insertAttendanceDateSettings(dateSettings);

                //创建考勤组对象
                AttendanceGroupInfo attendanceGroupInfo = new AttendanceGroupInfo();
                attendanceGroupInfo.setcTime(date);
                attendanceGroupInfo.setAttendanceGroupId(groupID);
                attendanceGroupInfo.setAttendanceGroupName(groupName.toString());
                attendanceGroupInfo.setAttendanceType(Integer.valueOf(attendanceType.toString()));
                if(null != adminAttendanceDate){
                    attendanceGroupInfo.setCheckPointIds(JSON.toJSONString(adminAttendanceDate));
                }else{
                    attendanceGroupInfo.setCheckPointIds("");
                }
                attendanceGroupInfo.setAttendanceShiftId(shiftInfo.toString());
                attendanceGroupInfo.setWorkingDay(workingDays.toString());
                if(specialCheckIDs.size() != 0){
                    attendanceGroupInfo.setSpecialCheckIds(JSON.toJSONString(specialCheckIDs));
                }
                attendanceGroupInfo.setIsContainHoliday(Integer.valueOf(isContainHoliday.toString()));
                if(null != ruleInfo){
                    attendanceGroupInfo.setRulesId(ruleInfo.toString());
                }
                iAttendanceGroupInfoService.insertAttendanceGroupInfo(attendanceGroupInfo);

                resultEntity.setCode("S");
                resultEntity.setMsg("创建成功");
            }
            if(flag.equals("update")){
                Object groupID = map.get("groupID"); //获取需要更新的考勤组ID
                if(null != groupID){
                    AttendanceGroupInfo orgInfo = iAttendanceGroupInfoService.selectOneAttendanceGroupInfoByAgId(groupID.toString());

                    //String dateSettingsID = orgInfo.getAttendanceDateId();
                    //AttendanceDateSettings orgSettings = iAttendanceDateSettingsService.selectAttendanceDateSettingsBySettingsID(dateSettingsID);
                    //设置更新值
                    //orgSettings.setmTime(date);
                    //orgSettings.setWorkingDay(workingDays.toString());
                    //orgSettings.setIsContainHoliday(Integer.valueOf(isContainHoliday.toString()));
                    //orgSettings.setAttendanceShiftId(shiftInfo.toString());
                    //iAttendanceDateSettingsService.updateAttendanceDateSettings(orgSettings);

                    orgInfo.setWorkingDay(workingDays.toString());
                    orgInfo.setIsContainHoliday(Integer.valueOf(isContainHoliday.toString()));
                    orgInfo.setAttendanceShiftId(shiftInfo.toString());

                    orgInfo.setmTime(date);
                    orgInfo.setAttendanceGroupName(groupName.toString());
                    orgInfo.setAttendanceType(Integer.valueOf(attendanceType.toString()));
                    if(null != ruleInfo){
                        orgInfo.setRulesId(ruleInfo.toString());
                    }
                    if(null != adminAttendanceDate){
                        orgInfo.setCheckPointIds(JSON.toJSONString(adminAttendanceDate));
                    }else{
                        orgInfo.setCheckPointIds("");
                    }
                    iAttendanceGroupInfoService.updateAttendanceGroupInfo(orgInfo);
                    resultEntity.setCode("S");
                    resultEntity.setMsg("更新成功");
                }else {
                    resultEntity.setCode("F");
                    resultEntity.setMsg("创建失败，原因：参数不正确");
                }
            }
        }else{
            resultEntity.setCode("F");
            resultEntity.setMsg("创建失败，原因：参数不正确");
        }
        return resultEntity;
    }


    /**
     * 将特殊打卡日期和不打卡日期做持久化操作
     * @param object
     * @param date
     * @param flag
     * @return
     */
    private List<String> doInsertSpecialCheckDate(Object object, Date date, String flag){
        List<String> ids = new ArrayList<>();
        JSONArray dateArray = JSON.parseArray(JSON.toJSONString(object));
        int count = 0;
        for (Object obj : dateArray
             ) {
            SpecialCheckDate scd = new SpecialCheckDate();
            JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(obj));
            scd.setcTime(date);
            String id = UUIDUtil.createUUID();
            ids.add(id);
            scd.setSpecialCheckId(id);
            if(flag.equals("B")){ //打卡标志，A为不打卡标志，表示该日期不需要打卡，B为打卡标志，表示该日期需要打卡
                try{
                    scd.setSpecialDate(dateUtil.formatDateByString(jsonObject.getString("checkDate")));
                }catch (ParseException pe){
                    pe.printStackTrace();
                }
                scd.setCheckFlag(flag);
            }
            if(flag.equals("A")){ //打卡标志，A为不打卡标志，表示该日期不需要打卡，B为打卡标志，表示该日期需要打卡
                try{
                    scd.setSpecialDate(dateUtil.formatDateByString(jsonObject.getString("noCheckDate")));
                }catch (ParseException pe){
                    pe.printStackTrace();
                }
                scd.setCheckFlag(flag);
            }
            count = count + iSpecialCheckDateService.insertSpecialCheckDate(scd);
        }
        return ids;
    }


    /**
     * 传入一个部门ID和部门ID集合，判断是否包含，包含则返回true，不包含则返回false
     * @param deptID
     * @param deptList
     * @return
     */
    private boolean isContainedDept(long deptID, List<Long> deptList){
        Long did = deptID;
        if(deptList.indexOf(did) == -1){
            return false;
        }else{
            return true;
        }
    }

}
